#pragma once
#include <iostream>
#include <pthread.h>
#include <vector>
#include <queue>
#include <mutex>
#include <functional>


#include "task.hpp"
const static int N = 5;

typedef void(*func_t)(void*,void*); 
template <class T>

class ThreadPool
{
public:
    ThreadPool(func_t callback,void* args1,void* args2,int num) 
    : num_(num), threads_(num),callback_(callback),args1_(args1),args2_(args2)
    {
        pthread_mutex_init(&mtx_, nullptr);
        pthread_cond_init(&cond_, nullptr);
    }
    void init()
    {
    }
    static void *threadRoutine(void *args)
    {
        pthread_detach(pthread_self());
        ThreadPool<T> *tp = static_cast<ThreadPool<T> *>(args);
        while (true)
        {
            tp->Lock();

            while (tp->IsEmpty())
            {
                // 等待
                tp->ThreadWait();
            }

            T t;
            t=tp->PopTask();
            tp->Unlock();

            t(); //处理任务不需要在临界区中处理
            tp->Args1_()=&(t.GetResult());
            tp->Args2_()=&(t.GetExitCode());
            // std::cout<<t.formatRes()<<std::endl;
            (*tp)();

        }
        return nullptr;
    }
    void* Args1_()
    {
        return args1_;
    }
    void *Args2_()
    {
        return args2_;
    }
    void operator()()
    {
        if(callback_)
         callback_(args1_,args2_);
    }
    T PopTask() // 走到这一定是只有一个线程 不需要加锁
    {
        T t = tasks_.front();
        tasks_.pop();
        return t;
    }
    // func_t callback(int result,int code)
    // {
    //     callback_(t.GetResult,t.GetExitCode);
    // }
    bool IsEmpty()
    {
        return tasks_.empty();
    }

    void Lock()
    {
        pthread_mutex_lock(&mtx_);
    }
    void Unlock()
    {
        pthread_mutex_unlock(&mtx_);
    }
    void ThreadWait()
    {
        pthread_cond_wait(&cond_, &mtx_);
    }
    void ThreadWakeUp()
    {
        pthread_cond_signal(&cond_);
    }
    void PushTask(const T &task)
    {
        Lock();
        tasks_.push(task);
        ThreadWakeUp();
        Unlock();
    }
    void start()
    {
        for (int i = 0; i < num_; i++)
        {
            pthread_create(&threads_[i], nullptr, threadRoutine, this);
        }
    }
    ~ThreadPool()
    {
        pthread_mutex_destroy(&mtx_);
        pthread_cond_destroy(&cond_);
    }

private:
    int num_;
    std::vector<pthread_t> threads_;
    std::queue<T> tasks_; // 使用stl自动扩容的特性,充当临界资源的角色
    pthread_mutex_t mtx_;
    pthread_cond_t cond_;
    func_t callback_;
    void* args1_;
    void* args2_;
};